#include "GAF_Scene.h"
#include "GAF_PublicFace.h"

namespace GAF
{
	Scene::Scene()
	{
		m_pFocus		= NULL;
		m_isFullWindow		= false;
		m_pBackScene		= NULL;
		m_nReturn		= GAF_ID_OK;
		m_pLayout		= NULL;
		m_pWindow		= NULL;
		m_pCanvas		= NULL;
		m_isUpdateCanvas	= false;
		m_pPlatform		= NULL;
		m_State			= SCENE_CREATE;
		m_isAllowExit		= false;

		SetVisible_a(false);

	}

	Scene::~Scene()
	{
	}

	void Scene::LoadLayout(Layout* pLayout)
	{
		GAF_CHECK(m_pLayout == NULL);
		GAF_CHECK(pLayout != NULL);

		m_pLayout = pLayout;

		UpdateCanvas();
	}

	void Scene::UnloadLayout()
	{
		GAF_CHECK(m_pLayout != NULL);

		m_pLayout = NULL;

		UpdateCanvas();
	}

	Layout* Scene::GetLayout()
	{
		return m_pLayout;
	}

	bool Scene::SetWindow(Window* pWindow)
	{
		GAF_CHECK_R(pWindow != NULL, false);
		GAF_CHECK_R(m_State == SCENE_FREE, false);

		if(m_pWindow != pWindow && m_pCanvas != NULL)
		{
			m_pCanvas->ClearGarphics();
			GAF_pTHEPLATFORM->DeleteCanvas(m_pCanvas);
			m_pCanvas = NULL;
		}

		m_pWindow = pWindow;

		if(m_pCanvas == NULL)
		{
			m_pPlatform = GAF_pTHEPLATFORM;
 			m_pCanvas = m_pPlatform->NewCanvas(m_pWindow->GetHandle());
			m_isUpdateCanvas = true;
		}

		return true;
	}

	void Scene::Show()
	{
		GAF_pTHEWINDOW->ShowScene(this);
	}

	void Scene::Call()
	{
		GAF_pTHEWINDOW->CallScene(this);
	}

	bool Scene::Init(Bundle* pbdlParam)
	{
		GAF_CHECK_R(m_State == SCENE_CREATE, false);

		if(!SUPER(Face)->Init(pbdlParam))
			return false;
		
		// 添加Layout布局
		if(m_pLayout != NULL)
			AddGraphics(m_pLayout);

		// 添加公共界面
		PublicFace::AddToScene(this);

		m_State = SCENE_FREE;
		return true;
	}

	bool Scene::Start(Scene* pBackScene)
	{
		GAF_CHECK_R(m_State == SCENE_FREE, false);
		GAF_CHECK_R(m_pWindow != NULL, false);
		GAF_CHECK_R(m_pCanvas != NULL, false);
		m_State = SCENE_START;

		if(!OnStart())
			return false;

		if(!m_pCanvas->Enabled())
			return false;

		UpdateCanvas();
		ResetCanvas();
		SetVisible_a(true);

		// 设置底层场景
		m_pBackScene = pBackScene;

		// 设置焦点
		ms_ppFocus = &m_pFocus;
		m_pFocus = this;

		m_State = SCENE_RUN;
		m_isAllowExit = false;

		return true;
	}

	void Scene::Resume()
	{
		if(m_State == SCENE_PAUSE)
		{
			OnResume();
			m_State = SCENE_RUN;
		}
	}

	void Scene::Update()
	{
		// 场景更新
		OnUpdate();
	}

	void Scene::Pause()
	{
		m_State = SCENE_PAUSE;
		OnPause();
	}

	ReturnID Scene::Exit(bool isEnforce)
	{
		// 如果为暂停状态，说明有Call场景。
		if(m_State == SCENE_PAUSE)
		{
			if(m_isAllowExit)
				// 说明是在退出流程上Call的场景，所以直接返回WAIT
				return ID_WAIT;
// 在主场景不允许退出的情况下，Call的场景已退出。故注销掉此部分代码。
/*			else
				// 说明是在运行流程上Call的场景，返回YES，以便可以向上询问Exit()。
				// 也避免再调用退出流程上Call的场景。
				return ID_YES;
*/
		}

		ReturnID _rid = isEnforce ? ID_YES : (IsFinish() ? ID_YES : ID_NO);
		if(_rid == ID_NO)
			_rid = OnExit(isEnforce);

		switch(_rid)
		{
		case ID_WAIT:
			m_isAllowExit = true;
			break;
		case ID_YES:
			m_isAllowExit = true;
			m_State = SCENE_END;
			break;
		case ID_NO:
			m_isAllowExit = false;
			break;
		}

		return _rid;
	}

	void Scene::End()
	{
		GAF_CHECK(m_State == SCENE_END)

 		SetVisible_a(false);

		m_pCanvas->ClearGarphics();
		m_pCanvas->Disabled();

 		OnEnd();

		ms_ppFocus = &(m_pBackScene->m_pFocus);
		m_pBackScene = NULL;

		m_State = SCENE_FREE;
	}

	void Scene::Destroy()
	{
		GAF_CHECK(m_State == SCENE_FREE);

		OnDestroy();

		if(m_pCanvas != NULL)
		{
			m_pCanvas->ClearGarphics();
			GAF_pTHEPLATFORM->DeleteCanvas(m_pCanvas);
			m_pCanvas = NULL;
		}

		m_pWindow = NULL;
	}

	bool Scene::IsFinish()
	{
		return m_State >= SCENE_FINISH;
	}
	bool Scene::IsAllowExit()
	{
		return m_isAllowExit;
	}

	void Scene::CancelExit()
	{
		m_isAllowExit = false;
	}

	SceneState Scene::GetState()
	{
		return m_State;
	}

	int Scene::GetReturn()
	{
		return m_nReturn;
	}

	void Scene::UpdateCanvas()
	{
		m_isUpdateCanvas = true;
	}

	void Scene::ResetCanvas()
	{
		GAF_CHECK(m_pCanvas);

		if(!m_isUpdateCanvas)
			return;

		m_pCanvas->SetGraphicsTree((Graphics*)this);

		m_isUpdateCanvas = false;
	}

	void Scene::FullWindow(bool isFullWindow)
	{
		m_isFullWindow = isFullWindow;
	}

	bool Scene::IsFullWindow()
	{
		return m_isFullWindow;
	}

	Scene* Scene::GetBackScene()
	{
		return m_pBackScene;
	}

	Window* Scene::GetWindow()
	{
		return m_pWindow;
	}

	Size* Scene::GetWindowSize()
	{
		GAF_CHECK_R(GAF_pTHEWINDOW != NULL, NULL);
		return &GAF_pTHEWINDOW->GetSize_a();
	}

	Canvas* Scene::GetCanvas()
	{
		return m_pCanvas;
	}

	void Scene::Return(int nReturn)
	{
		m_nReturn = nReturn;
		m_State = SCENE_FINISH;
		m_isAllowExit = true;
	}

	void Scene::ReturnOK()
	{
		Return(GAF_ID_OK);
	}

	void Scene::ReturnCancel()
	{
		Return(GAF_ID_CANCEL);
	}

	void Scene::ReturnYes()
	{
		Return(GAF_ID_YES);
	}

	void Scene::ReturnNo()
	{
		Return(GAF_ID_NO);
	}

	void Scene::ReturnError(int nErrorCode)
	{
		if(nErrorCode >= GAF_ID_ERROR)
			Return(nErrorCode);
		else
			Return(GAF_ID_ERROR);
	}
}
